package com.bwie.coupon.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWTUtil;
import com.bwie.common.constants.JwtConstants;
import com.bwie.common.constants.TokenConstants;
import com.bwie.common.doamin.dto.AddCouponDTO;
import com.bwie.common.doamin.dto.CouponLIstDTO;
import com.bwie.common.doamin.model.SysUser;
import com.bwie.common.doamin.model.UserCoupon;
import com.bwie.common.doamin.vo.*;
import com.bwie.common.exceptions.BizException;
import com.bwie.common.result.PageResult;
import com.bwie.common.utils.JwtUtils;
import com.bwie.coupon.mapper.CouponMapper;
import com.bwie.coupon.service.CouponService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.support.HttpRequestHandlerServlet;

import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @author <a href="mailto:2943147140@qq.com">刘洋朔</a>
 * @version 1.0
 * @description:
 * @date 2025/9/9 13:30
 */
@Slf4j
@Service
public class CouponServiceImpl implements CouponService {
    @Autowired
    private CouponMapper couponMapper;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private RedisTemplate redisTemplate;
    //折扣券
    private static final String DISCOUNT = "1";
    //满减券
    private static final String AMOUNT = "2";

    /**
     * 获取优惠券列表
     * @param couponLIstDTO
     * @return
     */
    @Override
    public PageResult<CouponListVO> selCouponList(CouponLIstDTO couponLIstDTO) {
        PageHelper.startPage(couponLIstDTO.getPageNum(),couponLIstDTO.getPageSize());
        List<CouponListVO> ponListVOList = couponMapper.selectCouponList(couponLIstDTO);
        PageInfo<CouponListVO> couPonListVOPageInfo = new PageInfo<>(ponListVOList);
        return PageResult.toPageResult(couPonListVOPageInfo.getTotal(),couPonListVOPageInfo.getList());
    }

    /**
     * 获取优惠券类型
     * @return
     */
    @Override
    public List<CouponTypeVO> CouponTypeVO() {
        return couponMapper.CouponTypeVO();
    }

    /**
     * 获取优惠券适用类型
     * @return
     */
    @Override
    public List<CouponCategoryVO> CouponCategoryVO() {
        return couponMapper.CouponCategoryVO();
    }

    /**
     * 优惠券添加
     * @param addCouponDTO
     */
    @Override
    public void addCoupon(AddCouponDTO addCouponDTO) {
        //不同的优惠券类型不同的条件判断
        //满减
        if(addCouponDTO.getCouponType().equals(AMOUNT)){
            if(ObjUtil.isEmpty(addCouponDTO.getDiscountAmount())){
                throw new BizException("折扣金额不能为空");
            }
        }
        //折扣
        if(addCouponDTO.getCouponType().equals(DISCOUNT)){
            if(ObjUtil.isEmpty(addCouponDTO.getDiscountRate())){
                throw new BizException("折扣比例不能为空");
            }
        }
        //唯一校验
        String couponName = addCouponDTO.getCouponName();
        int count = couponMapper.selSingleCouPon(couponName);
        if(count > 0){
            throw new BizException("优惠券重名啦,请重新构思一个");
        }
        //正常添加
        couponMapper.addCoupon(addCouponDTO);
    }

    /**
     * 优惠券删除
     * @param couponId
     */
    @Override
    public void delCoupon(Long couponId) {
        if(ObjUtil.isEmpty(couponId)){
            throw new BizException("请选择要删除的优惠券");
        }
        //正常删除
        couponMapper.delCoupon(couponId);
        //对已领取优惠券的用户进行补偿
    }

    /**
     * 用户领取优惠券
     * @param couponId
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void getCoupon(Long couponId) {
        //获取当前登录用户信息
        SysUser userInfo = getCurrentLoginUserInfo();
        //根据当前用户信息判断该用户用没有该优惠券
        int count = couponMapper.selCouponCountByUserId(userInfo.getId(),couponId);
        if(count > 0){
            throw new BizException("每张优惠券,一个用户限领一次");
        }
        //获取优惠券信息
        CouponSimpleVO couponSimpleVO = couponMapper.selCouponInfoSimple(couponId);
        //算取过期时间
        DateTime dateTime = DateUtil.offsetDay(new Date(), couponSimpleVO.getValidDays());
        //给用户发放优惠券
        UserCoupon userCoupon = new UserCoupon();
        userCoupon.setCouponId(couponId);
        userCoupon.setUserId(userInfo.getId());
        userCoupon.setUseType(couponSimpleVO.getApplicableCategory());
        userCoupon.setExpirationDate(dateTime);
        couponMapper.sendCouponToUser(userCoupon);
        //领取数量加一,优惠券数量减一
        couponMapper.updateCouponDiffNum(couponId);
    }

    /**
     * 拿到对应的优惠券
     * @param productId
     * @return
     */
    @Override
    public List<CouponListVO> selCouponListById(Long productId) {
        if(ObjUtil.isEmpty(productId)){
            throw new BizException("请先选择商品");
        }
        //获取当前用户信息
        SysUser currentLoginUserInfo = getCurrentLoginUserInfo();
        Long userid = currentLoginUserInfo.getId();
        //利用商品id获取它的类型
        String type = couponMapper.selProductType(productId);
        //获取用户能使用的优惠券
        List<CouponListVO> couponListVOS = couponMapper.selCouponListById(userid,type);
        log.info("用户能用的优惠券有{}",couponListVOS);
        return couponListVOS;
    }

    /**
     * 获取用户自己优惠券列表
     * @param couponLIstDTO
     * @return
     */
    @Override
    public PageResult<UserCouponVO> ownCouponList(CouponLIstDTO couponLIstDTO) {
        PageHelper.startPage(couponLIstDTO.getPageNum(),couponLIstDTO.getPageSize());
        SysUser user = getCurrentLoginUserInfo();
        List<UserCouponVO> ponListVOList = couponMapper.ownCouponList(user.getId(),couponLIstDTO);
        PageInfo<UserCouponVO> couPonListVOPageInfo = new PageInfo<>(ponListVOList);
        return PageResult.toPageResult(couPonListVOPageInfo.getTotal(),couPonListVOPageInfo.getList());
    }

    /**
     * 拿到对应的优惠券的详细信息
     * @param couponId
     * @return
     */
    @Override
    public CouponListVO selCouponInfo(Long couponId) {
        SysUser user = getCurrentLoginUserInfo();
        return couponMapper.selCouponById(couponId,user.getId());
    }

    //获取当前登录用户信息
    private SysUser getCurrentLoginUserInfo() {
        String token = request.getHeader(TokenConstants.TOKEN);
        if(StrUtil.isBlank(token)){
            throw new BizException("登录超时,请重新登陆");
        }
        String userKey = JwtUtils.getUserKey(token);
        SysUser sysUser = (SysUser) redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        return sysUser;
    }
}
